﻿using System;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using PSE.Deployment.ConfigurationManager.Controls;
using PSE.Deployment.Engine.Enums;

namespace PSE.Deployment.SetupBase.UI
{
    public class BaseWindow : Window
    {
        #region Propriedades
        protected string ConfirmOnClosingMessage { get; set; }
        public StepNavigationAction? NavigationAction { get; set; }

        private bool _confirmOnClosing;
        protected bool ConfirmOnClosing
        {
            get
            {
                return _confirmOnClosing;
            }
            set
            {
                _confirmOnClosing = value;
            }
        }

        public bool AllowClose
        {
            get { return (bool)GetValue(AllowCloseProperty); }
            set
            {
                if (System.Threading.Thread.CurrentThread == this.Dispatcher.Thread)
                {
                    SetValue(AllowCloseProperty, value);
                }
                else
                {
                    this.Dispatcher.Invoke(new Action<DependencyProperty, object>(SetValue), AllowCloseProperty, value);
                }
            }
        }

        public static readonly DependencyProperty AllowCloseProperty = DependencyProperty.Register("AllowClose", typeof(bool), typeof(BaseWindow), new UIPropertyMetadata(true));

        public bool AllowCancel
        {
            get { return (bool)GetValue(AllowCancelProperty); }
            set
            {
                if (System.Threading.Thread.CurrentThread == this.Dispatcher.Thread)
                {
                    SetValue(AllowCancelProperty, value);
                }
                else
                {
                    this.Dispatcher.Invoke(new Action<DependencyProperty, object>(SetValue), AllowCancelProperty, value);
                }
            }
        }

        public static readonly DependencyProperty AllowCancelProperty = DependencyProperty.Register("AllowCancel", typeof(bool), typeof(BaseWindow), new UIPropertyMetadata(true));

        public bool ShowBackgroundLogo
        {
            get { return (bool)GetValue(ShowBackgroundLogoProperty); }
            set
            {
                if (System.Threading.Thread.CurrentThread == this.Dispatcher.Thread)
                {
                    SetValue(ShowBackgroundLogoProperty, value);
                }
                else
                {
                    this.Dispatcher.Invoke(new Action<DependencyProperty, object>(SetValue), ShowBackgroundLogoProperty, value);
                }
            }
        }

        public static readonly DependencyProperty ShowBackgroundLogoProperty = DependencyProperty.Register("ShowBackgroundLogo", typeof(bool), typeof(BaseWindow), new UIPropertyMetadata(true));

        #endregion

        #region Construtor
        public BaseWindow()
        {
            this.Loaded += new RoutedEventHandler(BaseWindow_Loaded);
            this.MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(BaseWindow_MouseLeftButtonDown);
            this.WindowStartupLocation = WindowStartupLocation.CenterScreen;

            ChangeStyle();

            if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
            {
                ChangeIcon();
            }
        }

        protected virtual void ChangeStyle()
        {
            this.SetResourceReference(BaseWindow.StyleProperty, "BaseWindowStyle");
        }

        public void ChangeIcon()
        {
            MemoryStream memoryStream = new MemoryStream();
            PngBitmapDecoder pngBitmapDecoder;
            System.Drawing.Icon icon;
            Stream stream = null;

            Assembly entryAssembly = System.Reflection.Assembly.GetEntryAssembly();

            foreach (string resource in entryAssembly.GetManifestResourceNames())
            {
                if (resource.EndsWith(".ico"))
                {
                    stream = entryAssembly.GetManifestResourceStream(resource);
                    break;
                }
            }

            if (stream != null)
            {
                icon = new System.Drawing.Icon(stream);
                icon.ToBitmap().Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);

                memoryStream.Seek(0, SeekOrigin.Begin);

                pngBitmapDecoder = new PngBitmapDecoder(memoryStream, BitmapCreateOptions.None, BitmapCacheOption.Default);

                this.Icon = pngBitmapDecoder.Frames[0];
            }
        }

        #endregion

        #region Eventos Mouse
        void BaseWindow_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
                this.DragMove();
        }
        #endregion

        #region Eventos Window

        private void BaseWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Button BtnClose = this.FindName("BtnClose") as Button;
            if (BtnClose != null)
            {
                BtnClose.Click -= new RoutedEventHandler(BtnClose_Click);
                BtnClose.Click += new RoutedEventHandler(BtnClose_Click);
            }

            Button BtnCancel = this.FindName("BtnCancel") as Button;
            if (BtnCancel != null)
            {
                BtnCancel.Click -= new RoutedEventHandler(BtnCancel_Click);
                BtnCancel.Click += new RoutedEventHandler(BtnCancel_Click);
            }

            this.Activate();
        }

        #endregion

        #region Eventos Botão Close
        void BtnClose_Click(object sender, RoutedEventArgs e)
        {
            OnCloseClick(e);

            if (!e.Handled)
            {
                this.Close(this.ConfirmOnClosing);
            }
            else
            {
                this.NavigationAction = null;
            }
        }

        protected virtual void OnCloseClick(RoutedEventArgs e)
        {
            
        }

        public void Close(bool confirmClosing)
        {
            if (System.Threading.Thread.CurrentThread == this.Dispatcher.Thread)
            {
                ConfirmOnClosing = confirmClosing;

                base.Close();
            }
            else
            {
                this.Dispatcher.Invoke(new Action<bool>(Close), confirmClosing);
            }
        }

        public new void Close()
        {
            if (System.Threading.Thread.CurrentThread == this.Dispatcher.Thread)
            {
                this.Close(false);
            }
            else
            {
                this.Dispatcher.Invoke(new Action(Close));
            }
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            if (this.ConfirmOnClosing)
            {
                if (!NavigationAction.HasValue)
                {
                    if (ConfigurationMessageBox.Show("Deseja realmente encerrar o Setup?" + this.ConfirmOnClosingMessage, "Atenção", ConfigurationMessageBoxButton.YesNo, ConfigurationMessageBoxImage.Question) == ConfigurationMessageBoxResult.Yes)
                    {
                        this.NavigationAction = StepNavigationAction.Cancel;
                    }
                    else
                    {
                        e.Cancel = true;
                    }
                }
                else
                {
                    e.Cancel = true;
                }
            }
        }
        #endregion

        #region Eventos Botão Cancelar
        void BtnCancel_Click(object sender, RoutedEventArgs e)
        {
            OnCancelClick(e);
        }

        protected virtual void OnCancelClick(RoutedEventArgs e)
        {

        }
        #endregion
    }
}
